package com.google.agerasample.slice;

import static com.google.agera.Repositories.repositoryWithInitialValue;
import static com.google.agera.Result.absentIfNull;
import static com.google.agera.net.HttpFunctions.httpFunction;
import static com.google.agera.net.HttpRequests.httpGetRequest;

import static java.util.concurrent.Executors.newSingleThreadExecutor;

import com.google.agerasample.ResourceTable;
import com.google.agera.*;
import com.google.agera.net.HttpRequest;
import com.google.agera.net.HttpResponse;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Image;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.util.concurrent.ExecutorService;

public class MainAbilitySlice extends AbilitySlice implements Receiver<PixelMap>, Updatable {
    private static final ExecutorService NETWORK_EXECUTOR = newSingleThreadExecutor();
    private static final ExecutorService DECODE_EXECUTOR = newSingleThreadExecutor();
    private static final String BACKGROUND_BASE_URL =
            "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1606209783552&di=8d6bdca45b7af23a406ccac52a8f1415&imgtype=0&src=http%3A%2F%2Fa4.att.hudong.com%2F27%2F67%2F01300000921826141299672233506.jpg";

    private Repository<Result<PixelMap>> repository;
    private Image image;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        // Find the background view
        image = (Image) findComponentById(ResourceTable.Id_image_background);

        // 创建一个repository： 包括一个图片请求。Initially
        // 初始值：absent, 配置通过网络获取屏幕大小的图片。
        repository =
                repositoryWithInitialValue(Result.<PixelMap>absent())
                        .observe() // 在这个例子中不需要刷新背景图，也就是不需要被观察者
                        .onUpdatesPerLoop() // 在这个例子中每次都更新
                        .getFrom(
                                new Supplier<HttpRequest>() {
                                    @NonNull
                                    @Override
                                    public HttpRequest get() {
                                        return httpGetRequest(BACKGROUND_BASE_URL).compile();
                                    }
                                }) // 实现Http请求
                        .goTo(NETWORK_EXECUTOR) // 设置网络请求线程
                        .attemptTransform(httpFunction())
                        .orSkip() // 设置http请求，如果失败，跳过下面流程
                        .goTo(DECODE_EXECUTOR) // 设置解码线程
                        .thenTransform(
                                new Function<HttpResponse, Result<PixelMap>>() {
                                    @NonNull
                                    @Override
                                    public Result<PixelMap> apply(@NonNull HttpResponse response) {
                                        byte[] body = response.getBody();
                                        return absentIfNull(byteArray2PixelMap(body));
                                    }
                                }) // 解码图片, 如果失败返回absent
                        .onDeactivation(RepositoryConfig.SEND_INTERRUPT) // 中断线程
                        .compile(); // 创建repository
    }

    private PixelMap byteArray2PixelMap(byte[] body) {
        ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
        srcOpts.formatHint = "image/*";
        ImageSource imageSource = ImageSource.create(body, 0, body.length, srcOpts);
        if (imageSource == null) {
            return null;
        }
        ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
        decodingOpts.desiredSize = new Size(0, 0);
        decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
        decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
        return imageSource.createPixelmap(decodingOpts);
    }

    @Override
    public void onActive() {
        super.onActive();
        // 注册观察者，激活流程
        repository.addUpdatable(this);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        // 注销观察者，去激活流程
        repository.removeUpdatable(this);
    }

    @Override
    public void update() {
        // repository更新时 调用
        // 如果bitmap有效, 发送到下面的accept()方法
        repository.get().ifSucceededSendTo(this);
    }

    @Override
    public void accept(PixelMap value) {
        // 设置背景图片
        image.setPixelMap(value);
    }
}
